#if !defined(___SYS_C)
#define ___SYS_C

#if 0
#elif defined(___OS_WIN)
#include "win.c"
#elif defined(___OS_LIN)
#include "lin.c"
#else
#error Missing OS
#endif

/*====================== Variable =======================================*/

static N1 _TypSys[]=___SYS;
static N1 _TypOs[]=___OS;

Str TypSys=_TypSys;
Str TypOS=_TypOs;

/*====================== System =========================================*/

xx SysInit(xx)
{
#if defined(___OS_WIN)
  setmode(fileno(stdin),O_BINARY);
  setmode(fileno(stdout),O_BINARY);
  setmode(fileno(stderr),O_BINARY);
#endif
}

xx SysExit(N4 ret)
{ exit((int)ret);
}

/*====================== Time ===========================================*/

N4 TimeGet(N4 *msec)
{ struct timeb tmi; ftime(&tmi);
  if (msec) *msec=tmi.millitm;
  return ((N4)tmi.time);
}

N4 TimeSet(N4 tms,N4 msec)
{ return (-1);
}

N4 TimeConv(N1 bk,tTime *dt,N4 *tms)
{ time_t _tms=0; struct tm dti;

  if (bk)
  { if (tms) _tms=(time_t)*tms;
    if (dt)
    { /*!!!: LOCK required */
      dti=*localtime(&_tms);
      dt->year=dti.tm_year+1900;
      dt->month=dti.tm_mon+1;
      dt->day=dti.tm_mday;
      dt->hour=dti.tm_hour;
      dt->min=dti.tm_min;
      dt->sec=dti.tm_sec;
      dt->msec=0;
      dt->wday=dti.tm_wday ? dti.tm_wday : 7;
      dt->yday=dti.tm_yday+1;
    }
  } else
  { if (dt)
    { dti.tm_year=dt->year-1900;
      dti.tm_mon=dt->month-1;
      dti.tm_mday=dt->day;
      dti.tm_hour=dt->hour;
      dti.tm_min=dt->min;
      dti.tm_sec=dt->sec;
      dti.tm_wday=-1;
      dti.tm_yday=-1;
      _tms=mktime(&dti);
    }
  }
  if (tms) *tms=(N4)_tms;

  return ((N4)_tms);
}

/*====================== Environment ====================================*/

N4 FileNameConv(N1 d1,N1 d2,Str nam1,N4 nlen1,Str nam2)
{ N4 i; N1 c1;
  if (!nam1 || !nam2) return (-1);
  if (nlen1==-1) nlen1=StrLen(nam1);
  if (nlen1>FileNamLen) return (-1);
  for (i=0;i<nlen1;++i)
  { c1=*nam1++;
    if (c1==d1) c1=d2;
    *nam2++=c1;
  }
  *nam2=0; return (0);
}

N4 EnvGet(Str s1,Str s2,N4 l2)
{ Str m2; N4 ll;

  if (!s1) s1=S"";
  if (!s2) l2=0;
  if (!l2) return (-1);
  m2=(Str)getenv((CS)s1);
  ll=StrLen(m2); --l2;
  if (ll>l2) return (-ll);
  MemCpy(m2,s2,ll);
  s2[ll]=0;

  return (ll);
}

N4 EnvSet(Str s1,Str s2)
{ Str m1; N4 l1,l2; int ret;

  if (!s1) s1=S"";
  if (!s2) s2=S"";
  l1=StrLen(s1);
  l2=StrLen(s2);

  if (!(m1=MemGet(l1+1+l2+1))) return (-1);
  MemCpy(s1,m1,l1); m1[l1]='=';
  MemCpy(s2,m1+l1+1,l2); m1[l1+1+l2]=0;
  ret=putenv((CS)m1); MemRel(m1);
  if (ret==-1) return (-1);

  /*ret=setenv((CS)s1,(CS)s2,1);
  if (ret==-1) return (-1);*/

  return (0);
}

N4 CwdGet(Str nam,N4 nlen)
{ if (!nam) return (-1);
  if (!getcwd((CS)nam,nlen))
    return (-1); nlen=StrLen(nam);
  if (FileNameConv('\\','/',nam,nlen,nam))
    return (-1); else return (nlen);
}

N4 CwdSet(Str nam)
{ if (chdir((CS)nam)==-1)
    return (-1); else return (0);
}

N4 SysCmd(Str cmd)
{ if (!cmd) return (0);
  return ((N4)(I4)system((CS)cmd));
}

N4 DirList(Str nam,Str buf,N4 len)
{ N4 i,k,l,n; Str p1,p2;
  DIR *dir; struct dirent *ent;

  if (!buf) return (-1);

  /* Open directory */
  if (!(dir=opendir((CS)nam))) return (-1);
  /* Count total length */
  for (k=0,l=0;(ent=readdir(dir));
    l+=StrLen((Str)ent->d_name)+1,++k);
  if (len<l) { closedir(dir); return (-l); }
  else rewinddir(dir);
  /* Get entries */
  for (i=0,p2=buf;(ent=readdir(dir)) && i<k;p2+=n+1,++i)
  { p1=(Str)ent->d_name; n=StrLen(p1);
    if (p2-buf+n+1>l) { i=-1; break; }
    FileNameConv('\\','/',p1,n,p2);
  }
  /* Clean up */
  closedir(dir);
  if (ent || i!=k || p2-buf!=l)
    return (-1); else return (k);
}

/*====================== Module =========================================*/

#if !defined(___EXE)
N4 MemExe(Ptr mem,N4 len)
{ return (-1);
}
#endif

#if !defined(___LIB)
N4 LibOpen(Str nam)
{ return (-1);
}

xx LibClose(N4 id)
{
}

Ptr AdrGet(N4 id,Str nam)
{ return (NULL);
}

xx AdrRel(N4 id,Ptr adr)
{
}
#endif

/*====================== Thread =========================================*/

#if !defined(___THR)
N1 isth=0;
static N4 thNum=0;
static N4 thCur=0;

N4 ThBeg(fFun fun,N4 par)
{ N4 id1=thCur,id2;
  if (!fun) return (-1);
  id2=thCur=++thNum;
  fun(par); thCur=id1;

  return (id2);
}

xx ThEnd(N4 id)
{ if (!thCur) SysExit(0);
  fputs("Error: ThEnd\n",err);
  fflush(stderr); SysExit(-1);
}

N4 ThId(xx)
{ return (thCur);
}

N4 ThLkGet(xx)
{ return (0);
}

xx ThLkRel(N4 id)
{
}

N4 ThLkBeg(N4 id)
{ return (0);
}

N4 ThLkEnd(N4 id)
{ return (0);
}

/*-----------------------------------------------------------------------*/

N4 ThEvtGet(xx)
{ return (0);
}

xx ThEvtRel(N4 id)
{
}

N4 ThEvtSet(N4 id)
{ return (0);
};

N4 ThEvtNul(N4 id)
{ return (0);
};

xx ThEvtWait(N4 id,N4 lk,N4 tmm)
{
};
#endif

N4 ThEvtSet2(N4 id,N4 lk)
{ N4 ret1,ret2,ret3;

  ret1=ThLkBeg(lk);
  ret2=ThEvtSet(id);
  ret3=ThLkEnd(lk);

  return ((ret1||ret2||ret3) ? -1 : 0);
};

/*====================== Startup ========================================*/

#if defined(___OS_WIN)
N4 parset(Str *pp,Str p1,Str p2)
{ N4 num=0; N1 str=0,bsl=0;

  if (!p1) return (0);
  for (;*p1;++p1)
  { if (str)
    { if (bsl) { bsl=0; if (p2) *p2++=*p1; }
      else if (*p1=='\\') bsl=1;
      else if (*p1=='"') { str=0; if (p2) *p2++=0; }
      else if (p2) *p2++=*p1;
    } else
    { for (;*p1==' ' || *p1=='\t';++p1);
      if (!*p1) break; else { ++num; if (pp) *pp++=p2; }
      if (*p1=='"') { str=1; continue; }
      for (;*p1!=' ' && *p1!='\t' && *p1;++p1)
        if (p2) *p2++=*p1; if (p2) *p2++=0;
      if (!*p1) break; else --p1;
    }
  }

  return (num);
}
#endif

/*=======================================================================*/

#endif
